﻿using System;
using System.Linq;
using JetBrains.Annotations;
using Orchard.ContentManagement.Drivers;
using Orchard.Data;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Roles.Models;
using Orchard.Roles.Services;
using Orchard.Roles.ViewModels;
using Orchard.Security;
using Orchard.UI.Notify;
using Orchard.Environment.Extensions;
using Rework.CommerceHistory.Models;
using Rework.CommerceHistory.ViewModels;
using Nwazet.Commerce.Models;
using System.Collections.Generic;
using System.Web.Mvc;
using Orchard;

namespace Rework.CommerceHistory.Drivers {
    [OrchardFeature("Rework.CommerceHistory")]
    [UsedImplicitly]
    public class CommerceHistoryPartDriver : ContentPartDriver<CommerceHistoryPart> {
        private readonly IAuthorizationService _authorizationService;
        private readonly IAuthenticationService _authenticationService;
        private readonly IOrchardServices Services;
        private readonly INotifier _notifier;
        private readonly IMembershipService _membershipService;
        private const string TemplateName = "Parts/Commerce.CommerceHistory";
        
        public CommerceHistoryPartDriver( 
            INotifier notifier,
            IAuthenticationService authenticationService,
            IAuthorizationService authorizationService,
            IOrchardServices services,
            IMembershipService membershipService) {
            _authenticationService = authenticationService;
            _authorizationService = authorizationService;
            _notifier = notifier;
            Services = services;
            _membershipService = membershipService;
            T = NullLocalizer.Instance;
        }

        protected override string Prefix {
            get {
                return "CommerceHistory";
            }
        }

        public Localizer T { get; set; }

        protected override DriverResult Editor(CommerceHistoryPart commerceHistoryPart, dynamic shapeHelper) {
            // don't show editor without apply roles permission
            if (!_authorizationService.TryCheckAccess(StandardPermissions.SiteOwner, _authenticationService.GetAuthenticatedUser(), commerceHistoryPart))
                return null;

            return ContentShape("Parts_Commerce_History_Edit",
                    () => {
                        var viewModel = BuildEditorViewModel(commerceHistoryPart);
                        return shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: viewModel, Prefix: Prefix);
                    });
        }

        protected override DriverResult Editor(CommerceHistoryPart commerceHistoryPart, IUpdateModel updater, dynamic shapeHelper) {
            // don't apply editor without apply roles permission
            if (!_authorizationService.TryCheckAccess(StandardPermissions.SiteOwner, _authenticationService.GetAuthenticatedUser(), commerceHistoryPart))
                return null;

            var viewModel = new CommerceHistoryViewModel();

            if (updater.TryUpdateModel(viewModel, Prefix, null, null)) {

                // Need to check UserId (to make sure it is real)
                int userId = 0;
                bool isModelError = false;

                if (!String.IsNullOrEmpty(viewModel.UserName)) {
                    // Check to confirm that the username is valid
                    var user = _membershipService.GetUser(viewModel.UserName);
                    if (user != null) {
                        userId = user.Id;
                    }
                    else {
                        _notifier.Add(NotifyType.Error, T("The User Name does not exist."));
                        isModelError = true;
                    }
                }
                else {
                    _notifier.Add(NotifyType.Error, T("You must provide a User Name."));
                    isModelError = true;
                }

                if (!isModelError) {
                    commerceHistoryPart.UserId = userId;
                    commerceHistoryPart.ProductId = viewModel.ProductId;
                    commerceHistoryPart.Quantity = viewModel.Quantity;
                    commerceHistoryPart.Price = viewModel.Price;
                    commerceHistoryPart.IsPaymentConfirmed = viewModel.IsPaymentConfirmed;
                }
            }

            viewModel.Products = GetProducts(viewModel.ProductId);

            return ContentShape("Parts_Commerce_History_Edit",
                                () => shapeHelper.EditorTemplate(TemplateName: TemplateName, Model: viewModel, Prefix: Prefix));
        }
        
        private CommerceHistoryViewModel BuildEditorViewModel(CommerceHistoryPart part) {
            CommerceHistoryViewModel viewModel = new CommerceHistoryViewModel();
            viewModel.UserName = part.User == null ? "" : part.User.UserName;
            viewModel.ProductId = part.ProductId;
            viewModel.Quantity = part.Quantity;
            viewModel.Price = part.Price;
            viewModel.IsPaymentConfirmed = part.IsPaymentConfirmed;
            viewModel.Products = GetProducts(part.ProductId);

            return viewModel;
        }

        private IEnumerable<SelectListItem> GetProducts(int productId = -1) {
            IEnumerable<SelectListItem> products;

            products = Services.ContentManager.Query<ProductPart, ProductPartRecord>()
                .List()
                .Select(sl => new SelectListItem() {
                    Value = sl.Id.ToString(),
                    Text = Services.ContentManager.GetItemMetadata(sl).DisplayText,
                    Selected = sl.Id == productId,
                });

            return products;
        }

        //protected override void Importing(UserRolesPart part, ContentManagement.Handlers.ImportContentContext context) {
        //    var roles = context.Attribute(part.PartDefinition.Name, "Roles");
        //    if(string.IsNullOrEmpty(roles)) {
        //        return;
        //    }

        //    var userRoles = roles.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);

        //    // create new roles
        //    foreach (var role in userRoles) {
        //        var roleRecord = _roleService.GetRoleByName(role);

        //        // create the role if it doesn't already exist
        //        if (roleRecord == null) {
        //            _roleService.CreateRole(role);
        //        }
        //    }

        //    var currentUserRoleRecords = _productRolesRepository.Fetch(x => x.UserId == part.ContentItem.Id).ToList();
        //    var currentRoleRecords = currentUserRoleRecords.Select(x => x.Role).ToList();
        //    var targetRoleRecords = userRoles.Select(x => _roleService.GetRoleByName(x)).ToList();
        //    foreach (var addingRole in targetRoleRecords.Where(x => !currentRoleRecords.Contains(x))) {
        //        _productRolesRepository.Create(new UserRolesPartRecord { UserId = part.ContentItem.Id, Role = addingRole });
        //    }
        //}

        //protected override void Exporting(UserRolesPart part, ContentManagement.Handlers.ExportContentContext context) {
        //    context.Element(part.PartDefinition.Name).SetAttributeValue("Roles", string.Join(",", part.Roles));
        //}
    }
}